/*
 * DictionaryTermsFile_test.cpp
 *
 *  Created on: Oct 12, 2012
 *      Author: m
 */

#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <string>
#include "DictionaryTermsFile.h"

#define _LINE_BUFFER_SIZE 40
#define _LONG_SERIALIZATION_ARG  "-l"
#define _SHORT_SERIALIZATION_ARG "-s"
#define _TO_BIN_MODE_ARG "-tobin"
#define _TO_TXT_MODE_ARG "-totxt"

void invalid_args()
{
    std::cerr << "Argumentos inválidos. " << std::endl
              <<"Uso: dtf_ts read_buffer_size write_buffer_rsize serialization_mode operation_mode input output" << std::endl
              << "Descripción:" << std::endl
              << "\t serialization_mode:" << std::endl
              << "\t\t" << _LONG_SERIALIZATION_ARG  << ": Incluye el id random al serializar." << std::endl
              << "\t\t" << _SHORT_SERIALIZATION_ARG << ": Omite el id random al serializar." << std::endl
              << "\t operation_mode:" << std::endl
              << "\t\t" << _TO_BIN_MODE_ARG << ": Se lee un archivo de texto, donde cada línea se interpreta como un término, y se crea un archivo binario." << std::endl
              << "\t\t" << _TO_TXT_MODE_ARG << ": Se lee un archivo binario y se crea uno de texto, donde cada línea representa un término." << std::endl;
    exit( 1 );
}

int main( int argc, char* argv[] )
{

    std::fstream textFile;
    std::unique_ptr<DictionaryTermsFile> dictionary;
    bool includeRandom;
    bool tobinModeOn;
    char *inFileNameArg, *outFileNameArg, *readBufferSizeArg, *writeBufferSizeArg, *serializationModeArg, *operationModeArg;
    int readBufferSize, writeBufferSize;
    std::shared_ptr<DictionaryTerm> tempBuffer;

    // Valido y parseo argumentos (dsp podria usar una libreria...)
    if ( argc != 7 )
        invalid_args();

    readBufferSizeArg = argv[1];
    writeBufferSizeArg = argv[2];
    serializationModeArg = argv[3];
    operationModeArg = argv[4];
    inFileNameArg = argv[5];
    outFileNameArg = argv[6];

    // Parseo y valido Modo de Serializacion
    if ( strcmp( serializationModeArg, _LONG_SERIALIZATION_ARG ) == 0 )
        includeRandom = true;
    else
        if ( strcmp( serializationModeArg, _SHORT_SERIALIZATION_ARG ) == 0 )
            includeRandom = false;
        else
            invalid_args();

    // Parseo y valido Modo de Operacion
    if ( strcmp( operationModeArg, _TO_BIN_MODE_ARG ) == 0 )
        tobinModeOn = true;
    else
        if ( strcmp( operationModeArg, _TO_TXT_MODE_ARG ) == 0 )
            tobinModeOn = false;
        else
            invalid_args();

    // Parseo y valido Tamaños de Buffers
    readBufferSize  = atoi( readBufferSizeArg );
    writeBufferSize = atoi( writeBufferSizeArg );

    if ( readBufferSizeArg <= 0 || writeBufferSizeArg <= 0 )
        invalid_args();

    dictionary.reset( new DictionaryTermsFile( readBufferSize, writeBufferSize, includeRandom ) );

    if ( tobinModeOn )
    {
        textFile.open( inFileNameArg, std::ios_base::in );
        dictionary->open( outFileNameArg, std::ios_base::out | std::ios_base::trunc );

        int i = 0;
        char textBuffer[_LINE_BUFFER_SIZE];

        while ( textFile.getline( textBuffer, _LINE_BUFFER_SIZE ) )
        {
            tempBuffer.reset( new DictionaryTerm( textBuffer, i ) );
            dictionary->put( tempBuffer.get() );
            i++;
        }

    }
    else
    {

        dictionary->open( inFileNameArg, std::ios_base::in );
        textFile.open( outFileNameArg, std::ios_base::out | std::ios_base::trunc );

        while ( dictionary->hasNext() )
        {
            tempBuffer = dictionary->get();
            textFile << tempBuffer->getRandomKey() << " " << tempBuffer->getReserved() << " " << tempBuffer->getTerm() << std::endl;
        }

    }

    textFile.close();
    dictionary->close();

    return 0;
}
